package com.asman.worker.widgets.singleFile

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.util.AttributeSet
import android.view.View
import android.widget.*
import androidx.annotation.DrawableRes
import androidx.fragment.app.FragmentActivity
import com.alibaba.sdk.android.oss.ClientException
import com.alibaba.sdk.android.oss.ServiceException
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask
import com.alibaba.sdk.android.oss.model.PutObjectRequest
import com.alibaba.sdk.android.oss.model.PutObjectResult
import com.asman.base.lib.glide.GlideApp
import com.asman.customerview.extensions.isMulti
import com.asman.worker.widgets.multiFile.ImageUploadData
import com.asman.oss.my.OSSUpload
import com.asman.worker.R
import com.asman.worker.rn.NativeTakePhoto
import com.facebook.react.bridge.BaseActivityEventListener
import com.facebook.react.bridge.ReactContext
import com.jph.takephoto.model.TResult
import com.makeramen.roundedimageview.RoundedImageView
import com.utils.PhotoBottomSheet
import com.utils.TakePhotoCallBack
import showToast

/**
 * 上传图片
 */
class SingleImageUploadLayout @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    private var ivImg: ImageView
    private var layoutAdd: LinearLayout
    private var ivAdd: ImageView
    private var tvAdd: TextView
    private var ivDelete: ImageView
    private var progressBar: ProgressBar
    private var ivHover: RoundedImageView
    private var tvUploadResult: TextView
    private var tvEmpty: TextView
    private var tvError: TextView
    private var ivPlayer: ImageView

    lateinit var data: ImageUploadData

    private var text: String? = ""
    private var addSrc: Int = R.drawable.ic_add

    var videoEnable: Boolean = false

    init {
        val ta = context.obtainStyledAttributes(attrs, R.styleable.SingleImageUploadLayout)
        val n = ta.indexCount
        for (i in 0 until n) {
            val attr = ta.getIndex(i)
            if (attr == R.styleable.SingleImageUploadLayout_android_text) {
                text = ta.getString(attr)
            }
            if (attr == R.styleable.SingleImageUploadLayout_android_src) {
                addSrc = ta.getResourceId(attr, R.drawable.ic_add)
            }
        }
        ta.recycle()

        View.inflate(context, R.layout.layout_upload_big_image, this)
        ivImg = findViewById(R.id.iv_img)
        ivAdd = findViewById(R.id.iv_add)
        layoutAdd = findViewById(R.id.layout_add)
        tvAdd = findViewById(R.id.tv_add)
        ivDelete = findViewById(R.id.iv_delete)
        progressBar = findViewById(R.id.progressBar)
        ivHover = findViewById(R.id.iv_hover)
        tvUploadResult = findViewById(R.id.tv_upload_result)
        tvEmpty = findViewById(R.id.tv_empty)
        tvError = findViewById(R.id.tv_error)
        ivPlayer = findViewById(R.id.iv_play)

        tvAdd.text = text
        ivAdd.setImageResource(addSrc)
        initType(ImageUploadData(status = 0))
    }

    fun setTitle(title: String) {
        tvAdd.text = title
    }

    fun setImage(@DrawableRes resId: Int) {
        addSrc = resId
        ivAdd.setImageResource(addSrc)
    }

    lateinit var photoBottomSheet: PhotoBottomSheet

    private val mActivityEventListener = object : BaseActivityEventListener() {
        override fun onActivityResult(
            activity: Activity?, requestCode: Int, resultCode: Int, data: Intent?
        ) {
            photoBottomSheet.onActivityResult(requestCode, resultCode, data)
        }
    }

    var reactContext: ReactContext? = null
        set(value) {
            field = value
            value?.addActivityEventListener(mActivityEventListener)
        }

    fun getModule(reactContext: ReactContext): NativeTakePhoto {
        return reactContext.getNativeModule(NativeTakePhoto::class.java)
    }

    abstract class OnCallBack {
        open fun onAddClickListener() {}

        open fun onDeleteClickListener(data: ImageUploadData) {}

        open fun onImageListener(data: ImageUploadData) {}
    }

    var callBack: OnCallBack? = null

    fun setOnCallBackListener(callBack: OnCallBack?) {
        this.callBack = callBack
    }

    fun updateProgress(uploadProgress: Int) {
        data.uploadProgress = uploadProgress
        progressBar.progress = uploadProgress
    }

    fun initType(data: ImageUploadData) {
        this.data = data
        when (data.status) {
            0 -> { //添加
                ivDelete.visibility = View.GONE
                progressBar.visibility = View.GONE
                tvUploadResult.visibility = View.GONE
                ivHover.visibility = View.GONE
                tvEmpty.visibility = View.GONE
                tvError.visibility = View.GONE
                layoutAdd.visibility = View.VISIBLE
                GlideApp.with(context).clear(ivImg)
                ivImg.background = context.getDrawable(R.drawable.selector_stroke_click)
                ivImg.setOnClickListener {
                    if (callBack == null) {
                        showPhotoDialog()
                    } else {
                        callBack?.onAddClickListener()
                    }
                }
            }
            1, 2 -> { //1:已添加，未开始上传   2:正在上传
                ivDelete.visibility = View.VISIBLE
                progressBar.visibility = View.VISIBLE
                tvUploadResult.visibility = View.GONE
                layoutAdd.visibility = View.GONE
                ivHover.visibility = View.VISIBLE
                tvEmpty.visibility = View.GONE
                tvError.visibility = View.GONE
                GlideApp.with(context).load(data.localPath).into(ivImg)
                ivDelete.setOnClickListener { delete(data) }
                ivImg.setOnClickListener {
                    //查看图片
                    callBack?.onImageListener(data)
                }
                if (data.status == 1) { //1:已添加，未开始上传
                    uploadFile(data.localPath)
                }
            }
            3 -> { //上传完成
                ivDelete.visibility = View.VISIBLE
                progressBar.visibility = View.GONE
                layoutAdd.visibility = View.GONE
                tvEmpty.visibility = View.GONE
                tvError.visibility = View.GONE
                ivHover.visibility = View.GONE
                tvUploadResult.visibility = View.GONE
                GlideApp.with(context).load(data.localPath).into(ivImg)
                ivDelete.setOnClickListener { delete(data) }
                ivImg.setOnClickListener {
                    //查看图片
                    callBack?.onImageListener(data)
                }
                if (data.localPath?.isMulti() == true) {
                    ivPlayer.visibility = View.VISIBLE
                } else {
                    ivPlayer.visibility = View.GONE
                }
            }
            4 -> { //上传失败
                ivDelete.visibility = View.VISIBLE
                progressBar.visibility = View.GONE
                layoutAdd.visibility = View.GONE
                tvEmpty.visibility = View.GONE
                tvError.visibility = View.GONE
                ivHover.visibility = View.VISIBLE
                tvUploadResult.visibility = View.VISIBLE
                GlideApp.with(context).load(data.localPath).into(ivImg)
                ivDelete.setOnClickListener { delete(data) }
                ivImg.setOnClickListener {
                    uploadFile(data.localPath) //重新上传
                }
            }
        }
        requestLayout()
    }

    //显示选择对话框
    fun showPhotoDialog() {
        photoBottomSheet = PhotoBottomSheet.get()
        if (reactContext != null) {
            getModule(reactContext!!).photoBottomSheet = photoBottomSheet
        }
        photoBottomSheet.show(
            (context as FragmentActivity).supportFragmentManager, 1,
            videoEnable,
            object : TakePhotoCallBack.OnChoosePhoneResult {
                override fun onHandlerSuccess(result: TResult) {
                    if (result.image != null) {
                        uploadFile(result.image.originalPath)
                    } else {
                        showToast("获取图片失败")
                    }
                }

                override fun onHandlerFailure(errorMsg: String) {
                }
            })
    }

    var bucketName: String? = null
    var endpoint: String? = null

    fun initOSS(bucketName: String?, endpoint: String?) {
        this.bucketName = bucketName
        this.endpoint = endpoint
    }

    var task: OSSAsyncTask<PutObjectResult>? = null

    //开始上传文件
    private fun uploadFile(localPath: String?) {
        if (localPath.isNullOrEmpty()) return
        if (bucketName == null || endpoint == null) {
            showToast("配置信息有误")
            return
        }
        data.status = 2
        data.localPath = localPath
        initType(data)
        task = OSSUpload.get(bucketName, endpoint)
            .asyncPutImage(data.localPath, object : OSSUpload.OnUploadListener {
                override fun onProgress(progress: Int) {
                    updateProgress(progress)
                }

                override fun onSuccess(request: PutObjectRequest?, result: PutObjectResult?) {
                    data.status = 3
                    updateProgress(100)
                    data.url = request?.objectKey
                    initType(data)
                }

                override fun onFailed(
                    request: PutObjectRequest?,
                    clientExcepion: ClientException?,
                    serviceException: ServiceException?
                ) {
                    if (task?.isCanceled != null && !task?.isCanceled!!) {
                        data.status = 4
                        updateProgress(0)
                        initType(data)
                    }
                }
            })
    }

    fun delete(data: ImageUploadData) {
        //删除本图片，刷新，并且停止上传
        data.status = 0
        data.localPath = null
        data.uploadProgress = 0
        data.url = null
        initType(data)
        onDestroy()
        callBack?.onDeleteClickListener(data)
    }

    //停止上传
    fun onDestroy() {
        task?.cancel()
    }

    fun showEmptyTips(text: String) {
        tvEmpty.text = text
        tvEmpty.visibility = View.VISIBLE
    }

    fun showErrorTips(text: String) {
        tvError.text = text
        tvError.visibility = View.VISIBLE
    }

    //Android 动态addView RN 页面不刷新问题
    override fun requestLayout() {
        super.requestLayout()
        post(measureAndLayout)
    }

    private val measureAndLayout = Runnable {
        measure(
            MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
            MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
        )
        layout(left, top, right, bottom)
    }

}